/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.app;

/**
 * Methods to handle String's
 * 
 * @author Francisco Morero Peyrona
 */
public final class StrWise
{
	//-------------------------------------------------------------------------//
	// PADDING
	//-------------------------------------------------------------------------//

	/**
	 * Returns a String with a certain amount of spaces at its left side
	 * <p>
	 * 
	 * @param s
	 *            String to pad on left side
	 * @param n
	 *            Final length of the String after being padded
	 *            <p>
	 * @return The padded String with requested spaces
	 */
	public static String padL( String s, int n )
	{
		return padString( s, n, true, ' ' );
	}

	//------------------------------------------------//

	/**
	 * Same as before, but instead of padd the String with spaces, the filling character is passed as last argument.
	 * <p>
	 * 
	 * @param s
	 *            String to pad on left side
	 * @param n
	 *            Final length of the String after being padded
	 * @param c
	 *            Character to fill with
	 *            <p>
	 * @return The padded String with requested character
	 */
	public static String padL( String s, int n, char c )
	{
		return padString( s, n, true, c );
	}

	//--------------------------------------------------//

	/**
	 * Returns a String with a certain amount of spaces at its right side
	 * <p>
	 * 
	 * @param s
	 *            String to pad on right side
	 * @param n
	 *            Final length of the String after being padded
	 *            <p>
	 * @return The padded String with requested spaces
	 */
	public static String padR( String s, int n )
	{
		return padString( s, n, false, ' ' );
	}

	//-------------------------------------------------//

	/**
	 * Same as before, but instead of padd the String with spaces, the filling character is passed as last argument.
	 * <p>
	 * 
	 * @param s
	 *            String to pad on right side
	 * @param n
	 *            Final length of the String after being padded
	 * @param c
	 *            Character to fill with
	 *            <p>
	 * @return The padded String with requested character
	 */
	public static String padR( String s, int n, char c )
	{
		return padString( s, n, false, c );
	}

	//-------------------------------------------------//

	private static synchronized String padString( String s, int n, boolean bLeft, char cFill )
	{
		if( s.length() == n )
		{
			return s;
		}
		else if( s.length() > n )
		{
			return s.substring( 0, n );
		}
		else
		{
			StringBuffer sRet = new StringBuffer( s );
			sRet.ensureCapacity( n ); // to increase speed.
			n = n - s.length(); // n = spaces to add.

			if( bLeft )
				for( int i = 0; i < n; i++ )
					sRet.insert( 0, cFill );
			else
				for( int i = 0; i < n; i++ )
					sRet.append( cFill );

			return sRet.toString();
		}
	}

	//-------------------------------------------------------------------------//
	//   Replacements and Pattern matching
	//-------------------------------------------------------------------------//

	/**
	 * Returns a new string resulting from replacing first occurrence of <code>sOld</code> in <code>sSource</code> with
	 * <code>sNew</code>.
	 * <p>
	 * 
	 * @param sSource
	 *            Base string where the replacements take place.
	 * @param sOld
	 *            Sub string to be replaced.
	 * @param sNew
	 *            Sub string to replaced with.
	 */
	public static String replaceFirst( String sSource, String sOld, String sNew )
	{
		int nBegin = sSource.indexOf( sOld );
		int nEnd = nBegin + sOld.length();

		if( nBegin >= 0 )
			sSource = sSource.substring( 0, nBegin ) + sNew + sSource.substring( nEnd );

		return sSource;
	}

	/**
	 * Returns a new string resulting from replacing all occurrences of <code>sOld</code> in <code>sSource</code> with
	 * <code>sNew</code>.
	 * <p>
	 * 
	 * @param sSource
	 *            Base string where the replacements take place.
	 * @param sOld
	 *            Sub string to be replaced.
	 * @param sNew
	 *            Sub string to replaced with.
	 */
	public static String replaceAll( String sSource, String sOld, String sNew )
	{
		int nBegin = sSource.indexOf( sOld );
		int nLen = sOld.length();
		int nEnd = nBegin + nLen;

		while( nBegin >= 0 )
		{
			sSource = sSource.substring( 0, nBegin ) + sNew + sSource.substring( nEnd );
			nBegin = sSource.indexOf( sOld, nBegin + sNew.length() );
			nEnd = nBegin + nLen;
		}

		return sSource;
	}

	//-------------------------------------------------------------------------//
	// Miscellaneous methods
	//-------------------------------------------------------------------------//

	/**
	 * Capitalize passed String.
	 * 
	 * @param s
	 *            String to modify
	 * @param bReplaceUnderscores
	 *            Should underscores ('_') be replace by blanks (' ')?
	 */
	public static String capitalize( String s, boolean bReplaceUnderscores )
	{
		if( s != null && s.length() > 0 )
		{
			if( bReplaceUnderscores )
				s = s.replace( '_', ' ' );

			char[] ac = s.toLowerCase().toCharArray();

			ac[0] = Character.toUpperCase( ac[0] );

			for( int n = 2; n < ac.length; n++ )
			{
				if( ac[n - 1] == ' ' )
					ac[n] = Character.toUpperCase( ac[n] );
				else
					ac[n] = Character.toLowerCase( ac[n] );
			}

			return String.valueOf( ac );
		}

		return s;
	}

	/**
	 * Normalize a file name.
	 * <p>
	 * Changes ' ' by '_' and only admits numbers and letters.
	 * 
	 * @param sName
	 *            File name to be normalized.
	 * @return Normalized file name.
	 */
	public static String normalizeFileName( String sName )
	{
		char[] acName = sName.trim().toCharArray();
		StringBuffer sb = new StringBuffer( acName.length );

		for( int n = 0; n < acName.length; n++ )
		{
			if( Character.isLetterOrDigit( acName[n] ) )
				sb.append( acName[n] );
			else if( acName[n] == ' ' )
				sb.append( '_' );
		}

		if( sb.length() == 0 )
			App.showMessage( "Wrong file name", "Wrong file name:\n   only letters, numbers and '_' ar admited." );

		return sb.toString();
	}

	/**
	 * Parses a String extracting tokens.
	 * <p>
	 * It uses internally <code>java.util.StringTokenizer</code>
	 * 
	 * @param source
	 *            Source string to parse
	 * @param seps
	 *            Separators to be used
	 * @return An array of <code>String</code> s with one <code>String</code> per token found in <code>source</code> or an
	 *         empty array if any one or both parameters were <code>null</code>
	 */
	public static String[] string2Array( String source, String seps )
	{
		String[] as = new String[ 0 ];

		if( source != null && seps != null )
		{
			java.util.StringTokenizer st = new java.util.StringTokenizer( source, seps, false );
			java.util.Vector v = new java.util.Vector();

			while( st.hasMoreElements() )
				v.add( st.nextToken().trim() );

			as = new String[ v.size() ];
			v.copyInto( as );
		}

		return as;
	}
}